Skip to content

feat(ramps-controller): public getSmartSelectedQuote + validateBuyAmount; scope-gate widening#9414

Draft
saustrie-consensys wants to merge 3 commits into
saustrie/ramps-controller-ui-logicfrom
saustrie/ramps-controller-phase2-selection
Draft

feat(ramps-controller): public getSmartSelectedQuote + validateBuyAmount; scope-gate widening#9414
saustrie-consensys wants to merge 3 commits into
saustrie/ramps-controller-ui-logicfrom
saustrie/ramps-controller-phase2-selection

Conversation

@saustrie-consensys

Copy link
Copy Markdown
Contributor

Explanation

Headless Buy "All Providers Support" Phase 2 core follow-on, stacked on #9409 (base branch saustrie/ramps-controller-ui-logic, not main).

Today the widened in-app quote pick lives in the private RampsController#pickInAppQuote, reachable only through the autoSelectProvider / restrictToKnownOrNativeProviders path that MM Pay's getRampsQuote uses. The mobile headless getQuotes facade does not trigger it, so selection is forked and the headless UI re-derives ordering. This PR promotes that logic to a public, pure, provider-agnostic module so both callers pick identically, and lays the non-breaking groundwork for retiring the Money V0 native-only scaffolding (P2.M6 + the non-breaking part of P2.M8).

What changed:

  • New quoteSelection.ts module exporting:
    • getSmartSelectedQuote(response, { scope, amount, fiat, providers, preferredProviderIds? }) - the promoted body of #pickInAppQuote, ranking preferredProviderIds -> reliability -> price -> first. It reuses the feat(ramps-controller): share provider/quote/error helpers with consumers #9409 isInAppOnlyQuote classification for the in-app filter (drops external-browser and custom-action quotes under in-app/off, keeps them under all) and enforces per-provider fiat limits up front.
    • validateBuyAmount({ amount, limit }) and fitsProviderLimits(quote, { amount, fiat, providers }) - the limit-fit check extracted from the inlined #pickInAppQuote logic, plus a BuyAmountValidation result type.
  • #pickInAppQuote is now a thin wrapper over getSmartSelectedQuote, feeding it the controller-owned order-history preference (#getPreferredProviderIdsFromOrders) as the top ranking rung. A returning user's previously-used provider now wins over the reliability/price winner on the widened pick.
  • P2.M8 groundwork (non-breaking): getQuotes now derives provider-widening from the getProviderScope scope (off = native-only kill switch; in-app/all = widen, then rank), re-keying the widening gate and the empty-response guard off scope. restrictToKnownOrNativeProviders is marked @deprecated in JSDoc but is still honored (OR-ed into the auto-select path) so existing callers (TPC getRampsQuote) are unaffected. scope: 'off' stays native-only. The option is not removed (that is a later breaking change).

All new logic is pure and provider-agnostic; deeplink schemes, redirect/callback URLs, navigation, and error taxonomy stay in the mobile consumer.

Tests: new quoteSelection.test.ts (ranking with/without preferredProviderIds, in-app filter under each scope, all scope, limit bounds, validateBuyAmount/fitsProviderLimits) plus new RampsController.test.ts cases (order-history preference on the widened pick, scope: 'off' still native-only with the deprecated flag, deprecated flag alone still honored). Full package suite green (612 tests), typecheck and lint clean.

References

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

Made with Cursor

…unt; scope-gate widening

Promote the private in-app pick to a public pure getSmartSelectedQuote in a
new quoteSelection module, ranking preferredProviderIds -> reliability ->
price -> first and reusing the shared isInAppOnlyQuote filter. Extract the
limit-fit check as public validateBuyAmount/fitsProviderLimits. Make
#pickInAppQuote a thin wrapper that feeds the controller-owned order-history
preference into the shared pick.

Groundwork for retiring the native-only scaffolding: derive getQuotes'
widening from provider-class scope and mark restrictToKnownOrNativeProviders
@deprecated while still honoring it (OR-ed in) so existing callers are
unaffected. scope: 'off' stays native-only.
@saustrie-consensys

Copy link
Copy Markdown
Contributor Author

@metamaskbot publish-preview

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Preview builds have been published. Learn how to use preview builds in other projects.

Expand for full list of packages and versions.
@metamask-previews/account-tree-controller@7.5.3-preview-88f166b01
@metamask-previews/accounts-controller@39.0.4-preview-88f166b01
@metamask-previews/address-book-controller@7.1.2-preview-88f166b01
@metamask-previews/ai-controllers@0.7.0-preview-88f166b01
@metamask-previews/analytics-controller@1.2.1-preview-88f166b01
@metamask-previews/analytics-data-regulation-controller@0.0.0-preview-88f166b01
@metamask-previews/announcement-controller@8.1.0-preview-88f166b01
@metamask-previews/app-metadata-controller@2.0.1-preview-88f166b01
@metamask-previews/approval-controller@9.0.2-preview-88f166b01
@metamask-previews/assets-controller@10.0.1-preview-88f166b01
@metamask-previews/assets-controllers@109.3.0-preview-88f166b01
@metamask-previews/authenticated-user-storage@3.0.0-preview-88f166b01
@metamask-previews/base-controller@9.1.0-preview-88f166b01
@metamask-previews/base-data-service@0.1.3-preview-88f166b01
@metamask-previews/bitcoin-regtest-up@1.0.0-preview-88f166b01
@metamask-previews/bridge-controller@77.3.2-preview-88f166b01
@metamask-previews/bridge-status-controller@74.0.2-preview-88f166b01
@metamask-previews/build-utils@3.0.4-preview-88f166b01
@metamask-previews/chain-agnostic-permission@1.7.0-preview-88f166b01
@metamask-previews/chomp-api-service@3.1.0-preview-88f166b01
@metamask-previews/claims-controller@0.5.3-preview-88f166b01
@metamask-previews/client-controller@1.0.1-preview-88f166b01
@metamask-previews/client-utils@0.0.0-preview-88f166b01
@metamask-previews/compliance-controller@2.1.0-preview-88f166b01
@metamask-previews/composable-controller@12.0.1-preview-88f166b01
@metamask-previews/config-registry-controller@0.4.1-preview-88f166b01
@metamask-previews/connectivity-controller@0.2.0-preview-88f166b01
@metamask-previews/controller-utils@12.3.0-preview-88f166b01
@metamask-previews/core-backend@6.5.0-preview-88f166b01
@metamask-previews/delegation-controller@3.0.2-preview-88f166b01
@metamask-previews/earn-controller@12.2.2-preview-88f166b01
@metamask-previews/eip-5792-middleware@3.0.4-preview-88f166b01
@metamask-previews/eip-7702-internal-rpc-middleware@0.1.1-preview-88f166b01
@metamask-previews/eip1193-permission-middleware@2.0.1-preview-88f166b01
@metamask-previews/ens-controller@19.1.5-preview-88f166b01
@metamask-previews/eth-block-tracker@15.0.1-preview-88f166b01
@metamask-previews/eth-json-rpc-middleware@23.1.3-preview-88f166b01
@metamask-previews/eth-json-rpc-provider@6.0.1-preview-88f166b01
@metamask-previews/foundryup@1.0.1-preview-88f166b01
@metamask-previews/gas-fee-controller@26.2.4-preview-88f166b01
@metamask-previews/gator-permissions-controller@4.2.2-preview-88f166b01
@metamask-previews/geolocation-controller@0.1.3-preview-88f166b01
@metamask-previews/java-tron-up@1.0.0-preview-88f166b01
@metamask-previews/json-rpc-engine@10.5.0-preview-88f166b01
@metamask-previews/json-rpc-middleware-stream@8.0.8-preview-88f166b01
@metamask-previews/keyring-controller@27.1.0-preview-88f166b01
@metamask-previews/local-node-utils@1.0.0-preview-88f166b01
@metamask-previews/logging-controller@8.0.2-preview-88f166b01
@metamask-previews/message-manager@14.1.2-preview-88f166b01
@metamask-previews/messenger@2.0.0-preview-88f166b01
@metamask-previews/messenger-cli@0.2.0-preview-88f166b01
@metamask-previews/money-account-api-data-service@0.0.0-preview-88f166b01
@metamask-previews/money-account-balance-service@2.1.2-preview-88f166b01
@metamask-previews/money-account-controller@0.3.3-preview-88f166b01
@metamask-previews/money-account-upgrade-controller@2.2.1-preview-88f166b01
@metamask-previews/multichain-account-service@11.1.0-preview-88f166b01
@metamask-previews/multichain-api-middleware@4.0.1-preview-88f166b01
@metamask-previews/multichain-network-controller@3.2.1-preview-88f166b01
@metamask-previews/multichain-transactions-controller@7.1.1-preview-88f166b01
@metamask-previews/name-controller@9.1.2-preview-88f166b01
@metamask-previews/network-controller@34.0.0-preview-88f166b01
@metamask-previews/network-enablement-controller@5.4.1-preview-88f166b01
@metamask-previews/notification-services-controller@25.0.0-preview-88f166b01
@metamask-previews/passkey-controller@2.0.1-preview-88f166b01
@metamask-previews/permission-controller@13.1.1-preview-88f166b01
@metamask-previews/permission-log-controller@5.1.0-preview-88f166b01
@metamask-previews/perps-controller@9.2.1-preview-88f166b01
@metamask-previews/phishing-controller@17.2.0-preview-88f166b01
@metamask-previews/platform-api-docs@0.0.0-preview-88f166b01
@metamask-previews/polling-controller@16.0.8-preview-88f166b01
@metamask-previews/preferences-controller@23.1.0-preview-88f166b01
@metamask-previews/profile-metrics-controller@4.0.1-preview-88f166b01
@metamask-previews/profile-sync-controller@28.2.0-preview-88f166b01
@metamask-previews/ramps-controller@15.1.0-preview-88f166b01
@metamask-previews/rate-limit-controller@7.0.1-preview-88f166b01
@metamask-previews/react-data-query@0.2.1-preview-88f166b01
@metamask-previews/remote-feature-flag-controller@4.2.2-preview-88f166b01
@metamask-previews/sample-controllers@5.0.3-preview-88f166b01
@metamask-previews/seedless-onboarding-controller@10.0.3-preview-88f166b01
@metamask-previews/selected-network-controller@26.1.5-preview-88f166b01
@metamask-previews/shield-controller@5.1.2-preview-88f166b01
@metamask-previews/signature-controller@39.2.7-preview-88f166b01
@metamask-previews/smart-transactions-controller@24.2.4-preview-88f166b01
@metamask-previews/snap-account-service@1.0.0-preview-88f166b01
@metamask-previews/social-controllers@2.3.1-preview-88f166b01
@metamask-previews/solana-test-validator-up@1.0.0-preview-88f166b01
@metamask-previews/stellar-quickstart-up@0.0.0-preview-88f166b01
@metamask-previews/storage-service@1.0.2-preview-88f166b01
@metamask-previews/subscription-controller@6.2.0-preview-88f166b01
@metamask-previews/transaction-controller@68.2.2-preview-88f166b01
@metamask-previews/transaction-pay-controller@23.17.4-preview-88f166b01
@metamask-previews/user-operation-controller@41.2.6-preview-88f166b01
@metamask-previews/wallet@7.0.0-preview-88f166b01
@metamask-previews/wallet-cli@0.0.0-preview-88f166b01

…tion to the param

A block-level @deprecated tag in the getQuotes JSDoc marked the whole method
deprecated (TSDoc has no per-param deprecation), flagging every getQuotes
caller. Move the deprecation note into the param description prose instead.
@saustrie-consensys

Copy link
Copy Markdown
Contributor Author

@metamaskbot publish-preview

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Preview builds have been published. Learn how to use preview builds in other projects.

Expand for full list of packages and versions.
@metamask-previews/account-tree-controller@7.5.3-preview-bbd2df29f
@metamask-previews/accounts-controller@39.0.4-preview-bbd2df29f
@metamask-previews/address-book-controller@7.1.2-preview-bbd2df29f
@metamask-previews/ai-controllers@0.7.0-preview-bbd2df29f
@metamask-previews/analytics-controller@1.2.1-preview-bbd2df29f
@metamask-previews/analytics-data-regulation-controller@0.0.0-preview-bbd2df29f
@metamask-previews/announcement-controller@8.1.0-preview-bbd2df29f
@metamask-previews/app-metadata-controller@2.0.1-preview-bbd2df29f
@metamask-previews/approval-controller@9.0.2-preview-bbd2df29f
@metamask-previews/assets-controller@10.0.1-preview-bbd2df29f
@metamask-previews/assets-controllers@109.3.0-preview-bbd2df29f
@metamask-previews/authenticated-user-storage@3.0.0-preview-bbd2df29f
@metamask-previews/base-controller@9.1.0-preview-bbd2df29f
@metamask-previews/base-data-service@0.1.3-preview-bbd2df29f
@metamask-previews/bitcoin-regtest-up@1.0.0-preview-bbd2df29f
@metamask-previews/bridge-controller@77.3.2-preview-bbd2df29f
@metamask-previews/bridge-status-controller@74.0.2-preview-bbd2df29f
@metamask-previews/build-utils@3.0.4-preview-bbd2df29f
@metamask-previews/chain-agnostic-permission@1.7.0-preview-bbd2df29f
@metamask-previews/chomp-api-service@3.1.0-preview-bbd2df29f
@metamask-previews/claims-controller@0.5.3-preview-bbd2df29f
@metamask-previews/client-controller@1.0.1-preview-bbd2df29f
@metamask-previews/client-utils@0.0.0-preview-bbd2df29f
@metamask-previews/compliance-controller@2.1.0-preview-bbd2df29f
@metamask-previews/composable-controller@12.0.1-preview-bbd2df29f
@metamask-previews/config-registry-controller@0.4.1-preview-bbd2df29f
@metamask-previews/connectivity-controller@0.2.0-preview-bbd2df29f
@metamask-previews/controller-utils@12.3.0-preview-bbd2df29f
@metamask-previews/core-backend@6.5.0-preview-bbd2df29f
@metamask-previews/delegation-controller@3.0.2-preview-bbd2df29f
@metamask-previews/earn-controller@12.2.2-preview-bbd2df29f
@metamask-previews/eip-5792-middleware@3.0.4-preview-bbd2df29f
@metamask-previews/eip-7702-internal-rpc-middleware@0.1.1-preview-bbd2df29f
@metamask-previews/eip1193-permission-middleware@2.0.1-preview-bbd2df29f
@metamask-previews/ens-controller@19.1.5-preview-bbd2df29f
@metamask-previews/eth-block-tracker@15.0.1-preview-bbd2df29f
@metamask-previews/eth-json-rpc-middleware@23.1.3-preview-bbd2df29f
@metamask-previews/eth-json-rpc-provider@6.0.1-preview-bbd2df29f
@metamask-previews/foundryup@1.0.1-preview-bbd2df29f
@metamask-previews/gas-fee-controller@26.2.4-preview-bbd2df29f
@metamask-previews/gator-permissions-controller@4.2.2-preview-bbd2df29f
@metamask-previews/geolocation-controller@0.1.3-preview-bbd2df29f
@metamask-previews/java-tron-up@1.0.0-preview-bbd2df29f
@metamask-previews/json-rpc-engine@10.5.0-preview-bbd2df29f
@metamask-previews/json-rpc-middleware-stream@8.0.8-preview-bbd2df29f
@metamask-previews/keyring-controller@27.1.0-preview-bbd2df29f
@metamask-previews/local-node-utils@1.0.0-preview-bbd2df29f
@metamask-previews/logging-controller@8.0.2-preview-bbd2df29f
@metamask-previews/message-manager@14.1.2-preview-bbd2df29f
@metamask-previews/messenger@2.0.0-preview-bbd2df29f
@metamask-previews/messenger-cli@0.2.0-preview-bbd2df29f
@metamask-previews/money-account-api-data-service@0.0.0-preview-bbd2df29f
@metamask-previews/money-account-balance-service@2.1.2-preview-bbd2df29f
@metamask-previews/money-account-controller@0.3.3-preview-bbd2df29f
@metamask-previews/money-account-upgrade-controller@2.2.1-preview-bbd2df29f
@metamask-previews/multichain-account-service@11.1.0-preview-bbd2df29f
@metamask-previews/multichain-api-middleware@4.0.1-preview-bbd2df29f
@metamask-previews/multichain-network-controller@3.2.1-preview-bbd2df29f
@metamask-previews/multichain-transactions-controller@7.1.1-preview-bbd2df29f
@metamask-previews/name-controller@9.1.2-preview-bbd2df29f
@metamask-previews/network-controller@34.0.0-preview-bbd2df29f
@metamask-previews/network-enablement-controller@5.4.1-preview-bbd2df29f
@metamask-previews/notification-services-controller@25.0.0-preview-bbd2df29f
@metamask-previews/passkey-controller@2.0.1-preview-bbd2df29f
@metamask-previews/permission-controller@13.1.1-preview-bbd2df29f
@metamask-previews/permission-log-controller@5.1.0-preview-bbd2df29f
@metamask-previews/perps-controller@9.2.1-preview-bbd2df29f
@metamask-previews/phishing-controller@17.2.0-preview-bbd2df29f
@metamask-previews/platform-api-docs@0.0.0-preview-bbd2df29f
@metamask-previews/polling-controller@16.0.8-preview-bbd2df29f
@metamask-previews/preferences-controller@23.1.0-preview-bbd2df29f
@metamask-previews/profile-metrics-controller@4.0.1-preview-bbd2df29f
@metamask-previews/profile-sync-controller@28.2.0-preview-bbd2df29f
@metamask-previews/ramps-controller@15.1.0-preview-bbd2df29f
@metamask-previews/rate-limit-controller@7.0.1-preview-bbd2df29f
@metamask-previews/react-data-query@0.2.1-preview-bbd2df29f
@metamask-previews/remote-feature-flag-controller@4.2.2-preview-bbd2df29f
@metamask-previews/sample-controllers@5.0.3-preview-bbd2df29f
@metamask-previews/seedless-onboarding-controller@10.0.3-preview-bbd2df29f
@metamask-previews/selected-network-controller@26.1.5-preview-bbd2df29f
@metamask-previews/shield-controller@5.1.2-preview-bbd2df29f
@metamask-previews/signature-controller@39.2.7-preview-bbd2df29f
@metamask-previews/smart-transactions-controller@24.2.4-preview-bbd2df29f
@metamask-previews/snap-account-service@1.0.0-preview-bbd2df29f
@metamask-previews/social-controllers@2.3.1-preview-bbd2df29f
@metamask-previews/solana-test-validator-up@1.0.0-preview-bbd2df29f
@metamask-previews/stellar-quickstart-up@0.0.0-preview-bbd2df29f
@metamask-previews/storage-service@1.0.2-preview-bbd2df29f
@metamask-previews/subscription-controller@6.2.0-preview-bbd2df29f
@metamask-previews/transaction-controller@68.2.2-preview-bbd2df29f
@metamask-previews/transaction-pay-controller@23.17.4-preview-bbd2df29f
@metamask-previews/user-operation-controller@41.2.6-preview-bbd2df29f
@metamask-previews/wallet@7.0.0-preview-bbd2df29f
@metamask-previews/wallet-cli@0.0.0-preview-bbd2df29f

@saustrie-consensys

Copy link
Copy Markdown
Contributor Author

@metamaskbot publish-preview

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant